package com.cirkana.viewer.data.security;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import java.util.List;

import com.cirkana.data.IDataColumnDef;
import com.cirkana.data.IDataTableDef;
import com.cirkana.data.security.IUserService;
import com.cirkana.serial.bin.BinarySerializationException;
import com.cirkana.serial.bin.BinarySerializationUtil;
import com.cirkana.serial.text.TextSerializationBuilder;
import com.cirkana.viewer.data.DataColumnDef;
import com.cirkana.viewer.data.LocalDataRecord;

public class UserService extends LocalDataRecord implements IUserService {

	protected static final String COLUMN_USER_ID = "USER_ID";
	protected static final String COLUMN_SERVICE_NAME = "SERVICE_NAME";
	protected static final String COLUMN_NICK_NAME = "NICK_NAME";
	protected static final String COLUMN_SECURITY_DATA = "SECURITY_DATA";

	public static final IDataTableDef tableDef = new UserServiceTableDef();

	protected Integer getUserId() {
		return this.getIntegerField(COLUMN_USER_ID);
	}

	protected void setUserId(Integer userId) {
		this.setIntegerField(COLUMN_USER_ID, userId);
	}

	protected String getServiceName() {
		return this.getStringField(COLUMN_SERVICE_NAME);
	}

	protected void setServiceName(String serviceName) {
		this.setStringField(COLUMN_SERVICE_NAME, serviceName);
	}

	@Override
	public String getNickName() {
		return this.getStringField(COLUMN_NICK_NAME);
	}

	@Override
	public void setNickName(String nickName) {
		this.setStringField(COLUMN_NICK_NAME, nickName);
	}

	private static final String DELIMITER = ";";

	@Override
	public String[] getSecurityData() {
		String value = this.getStringField(COLUMN_SECURITY_DATA);
		if (value == null)
			return null;
		else
			return value.split(DELIMITER);
	}

	@Override
	public void setSecurityData(String[] securityData) {
		if (securityData == null)
			this.setStringField(COLUMN_SECURITY_DATA, null);
		else {
			StringBuilder s = new StringBuilder();
			for (String d : securityData) {
				s.append(d);
				s.append(DELIMITER);
			}
			if (s.length() > 0)
				s.delete(s.length() - 1, s.length());
			this.setStringField(COLUMN_SECURITY_DATA, s.toString());
		}
	}

	@Override
	public void serialize(DataOutputStream out) throws BinarySerializationException {
		BinarySerializationUtil.serializeInteger(this.getUserId(), out);
		BinarySerializationUtil.serializeString(this.getServiceName(), out);
		BinarySerializationUtil.serializeString(this.getNickName(), out);
		BinarySerializationUtil.serializeStringArray(this.getSecurityData(), out);
	}

	@Override
	public void deserialize(DataInputStream in) throws BinarySerializationException {
		this.setUserId(BinarySerializationUtil.deserializeInteger(in));
		this.setServiceName(BinarySerializationUtil.deserializeString(in));
		this.setNickName(BinarySerializationUtil.deserializeString(in));
		this.setSecurityData(BinarySerializationUtil.deserializeStringArray(in));
	}

	@Override
	public String toText() {
		TextSerializationBuilder t = new TextSerializationBuilder();
		t.append("userId", this.getUserId());
		t.append("serviceName", this.getServiceName());
		t.append("nickName", this.getNickName());
		t.append("securityData", this.getSecurityData());
		return t.getTextSerialization();
	}

	static class UserServiceTableDef implements IDataTableDef {

		private static final String TABLE_NAME = "USER_SERVICES";
		private static final List<IDataColumnDef> TABLE_COLUMNS = new ArrayList<IDataColumnDef>();
		static {
			TABLE_COLUMNS.add(new DataColumnDef(0, COLUMN_USER_ID, int.class, true));
			TABLE_COLUMNS.add(new DataColumnDef(1, COLUMN_SERVICE_NAME, String.class, true));
			TABLE_COLUMNS.add(new DataColumnDef(2, COLUMN_NICK_NAME, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(3, COLUMN_SECURITY_DATA, String.class));
		}

		@Override
		public String getTableName() {
			return TABLE_NAME;
		}

		@Override
		public List<IDataColumnDef> getColumnsDef() {
			return TABLE_COLUMNS;
		}

		@Override
		public Class<?> getDataRecordType() {
			return UserService.class;
		}

	}
}
